package com.tanhua.server.service;

import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.tanhua.commons.templates.OssTemplate;
import com.tanhua.domain.db.UserInfo;
import com.tanhua.domain.mongo.FollowUser;
import com.tanhua.domain.mongo.Publish;
import com.tanhua.domain.mongo.Video;
import com.tanhua.domain.vo.PageResult;
import com.tanhua.domain.vo.VideoVo;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.mongo.FollowUserApi;
import com.tanhua.dubbo.api.mongo.VideoApi;
import com.tanhua.server.interceptor.UserHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Reference;
import org.bson.types.ObjectId;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Service
@Slf4j
public class VideoService {

    @Reference
    private VideoApi videoApi;

    @Reference
    private UserInfoApi userInfoApi;


    @Autowired
    private OssTemplate ossTemplate;


    @Autowired
    private FastFileStorageClient client;

    @Autowired
    private FdfsWebServer webServer;


    @Reference
    private FollowUserApi followUserApi;


    @Autowired
    private RedisTemplate<String,String> redisTemplate;


    @Autowired
    private VideoMqService videoMqService;

    /**
     * 查询视频列表
     * @param page
     * @param pagesize
     * @return
     */
    @Cacheable(value = "videoList",key = "#page+'_'+#pagesize") // 当前页  页面大小   1 10   当前页1  页面大小5
    public PageResult queryVideoList(Integer page, Integer pagesize) {
        log.info("========查询数据库得到视频列表=============>");
        //1. 得到视频的分页对象  pageResult  Video
        PageResult pageResult = findRecommend(page, pagesize, UserHolder.getUserId());
        if(pageResult==null) {
            pageResult = videoApi.findByPage(page, pagesize);
        }

        //2. 得到分页Items List<Video>
        List<Video> videoList = (List<Video>) pageResult.getItems();

        //3. 创建VoList，里面存储VideoVo
        List<VideoVo> voList = new ArrayList<>();

        //4.把Video转换为VideoVo
        if(videoList!=null){
            for (Video video : videoList) {
                VideoVo vo = new VideoVo();
                UserInfo userInfo = userInfoApi.findById(video.getUserId());
                if(userInfo!=null){
                    BeanUtils.copyProperties(userInfo,vo);
                }
                BeanUtils.copyProperties(video,vo);
                vo.setId(video.getId().toString());
                vo.setCover(video.getPicUrl()); //视频的封面
                vo.setSignature(video.getText());
                vo.setHasLiked(0); //是否已经点赞
                String key = "followUser_"+UserHolder.getUserId()+"_"+video.getUserId();
                if(redisTemplate.hasKey(key)){
                    vo.setHasFocus(1); //是否已经关注
                }else {
                    vo.setHasFocus(0); //是否已经关注
                }
                voList.add(vo);
            }
        }
        pageResult.setItems(voList);
        //5. 返回响应

        return pageResult;
    }

    //从redis中查找推荐的小视频
    private PageResult findRecommend(Integer page, Integer pagesize, Long userId) {
        //1. 先从reids中取出推荐的数据
        String key = "QUANZI_VIDEO_RECOMMEND_"+UserHolder.getUserId();
        String value = redisTemplate.opsForValue().get(key);
        //2. 判断是否为空,如果为null直接返回null
        if(value==null){
            //该用户没有推荐的信息
            return null;
        }
        String[] videoList = value.split(",");
        //3.计算startIndex、endIndex， startIndex开始取索引值， endIndex结束的索引值
        int startIndex = (page-1)*pagesize;
        if(startIndex<videoList.length){
            int endIndex = startIndex+pagesize-1;
            if(endIndex>=videoList.length){
                endIndex = videoList.length-1;
            }
            //4.把当前页面的pid存储到集合中查询对应的publish存储到集合中
            List<Long> vList = new ArrayList<>(); // 33,7,36,36,14,38,31
            for (int i = startIndex; i <=endIndex ; i++) {
                vList.add(Long.valueOf(videoList[i]));
            }

            //根据pList查找publish
            List<Video> resultList = videoApi.findByVids(vList);
            PageResult pageResult = new PageResult(page,pagesize,videoList.length,resultList);
            return pageResult;

        }
        //5. 返回pageREsult;
        return  null;
    }




    /**
     * 视频上传
     * @param videoThumbnail  视频封面
     * @param videoFile  视频
     * @param text  视频的标题
     * @return
     */
    @CacheEvict(value = "videoList",allEntries = true)
    public ResponseEntity uploadVideos(MultipartFile videoThumbnail, MultipartFile videoFile, String text) throws IOException {
        //1. 把图片上传到阿里云
        String picUrl = ossTemplate.upload(videoThumbnail.getOriginalFilename(), videoThumbnail.getInputStream());

        //2. 视频视频fastdfs  123.wmv
        String videoName = videoFile.getOriginalFilename();
        String extName = videoName.substring(videoName.lastIndexOf(".") + 1);
        StorePath storePath = client.uploadFile(videoFile.getInputStream(), videoFile.getSize(), extName, null);
        String videoUrl = webServer.getWebServerUrl()+storePath.getFullPath();

        //3.创建Video对象，封装参数
        Video video = new Video();
        video.setUserId(UserHolder.getUserId());
        if(text!=null) {
            video.setText(text);
        }else{
            video.setText("左手一个慢动作，右手再来一个慢动作");
        }
        video.setPicUrl(picUrl);
        video.setVideoUrl(videoUrl);
        video.setCreated(System.currentTimeMillis());
        video.setLikeCount(0);
        video.setCommentCount(0);
        video.setLoveCount(0);
        video.setId(ObjectId.get());

        // 4. 保存video
        videoApi.save(video);
        //发送消息到rocketmq上面
        videoMqService.videoMsg(video.getId().toString());
        //5. 返回响应
        return ResponseEntity.ok(null);
    }

    //关注用户
    public ResponseEntity followUser(Long followUserId) {
        //1. 获取当前登陆者
        Long userId = UserHolder.getUserId();
        //2. 创建Followuser对象， 补全参数
        FollowUser followUser = new FollowUser();
        followUser.setCreated(System.currentTimeMillis());
        followUser.setUserId(userId);
        followUser.setFollowUserId(followUserId);
        //3. 保存数据
        followUserApi.save(followUser);

        //4. 往redis中设置一个已经关注的标记
        String key = "followUser_"+userId+"_"+followUserId;
        redisTemplate.opsForValue().set(key,"1");

        //5. 返回响应
        return ResponseEntity.ok(null);
    }

    public ResponseEntity unFollowUser(Long followUserId) {
        //1. 删除关注的用户数据
        Long userId = UserHolder.getUserId();
        followUserApi.unfollowUser(userId,followUserId);
        //2 . 删除已经关注的标记
        String key = "followUser_"+userId+"_"+followUserId;
        redisTemplate.delete(key);

        //3. 返回响应
        return ResponseEntity.ok(null);
    }
}
